package com.saasovation.common;

import com.saasovation.common.annotation.TestContainers;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.containers.RabbitMQContainer;

public abstract class TestBase {

    protected static final String RABBITMQ_DOCKER_IMAGE_VERSION = "rabbitmq:3.13.7-management";
    protected static final String MYSQL_DOCKER_IMAGE_VERSION = "mysql:8.4.2";
    protected static final String TEST_DATABASE_NAME = "iddd_test";

    protected static MySQLContainer<?> mysqlContainer;
    protected static RabbitMQContainer rabbitMQContainer;

    protected static void initMySqlContainer(DynamicPropertyRegistry registry) {
        mysqlContainer = new MySQLContainer<>(MYSQL_DOCKER_IMAGE_VERSION);
        mysqlContainer.withDatabaseName(TEST_DATABASE_NAME);
        mysqlContainer.start();

        registryJdbcProperties(registry);
    }

    protected static void registryJdbcProperties(DynamicPropertyRegistry registry) {
        registry.add("jdbc.url", mysqlContainer::getJdbcUrl);
        registry.add("jdbc.username", mysqlContainer::getUsername);
        registry.add("jdbc.password", mysqlContainer::getPassword);
        registry.add("jdbc.driverClassName", mysqlContainer::getDriverClassName);
    }

    protected static void initRabbitMqContainer(DynamicPropertyRegistry registry) {
        rabbitMQContainer = new RabbitMQContainer(RABBITMQ_DOCKER_IMAGE_VERSION);
        rabbitMQContainer.start();

        registryRabbitMqProperties(registry);
    }

    protected static void registryRabbitMqProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.rabbitmq.host", rabbitMQContainer::getHost);
        registry.add("spring.rabbitmq.port", rabbitMQContainer::getAmqpPort);
        registry.add("spring.rabbitmq.username", rabbitMQContainer::getAdminUsername);
        registry.add("spring.rabbitmq.password", rabbitMQContainer::getAdminPassword);
    }

    protected static boolean useTestContainers(Class<?> clazz) {
        TestContainers annotation = clazz.getAnnotation(TestContainers.class);
        return annotation != null && (annotation.value() || annotation.use());
    }
}
